﻿#pragma once

#include <any>
#include <cstdint>
#include <ctime>
#include <functional>
#include <initializer_list>
#include <map>
#include <memory>
#include <set>
#include <sstream>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

namespace kratos {
namespace util {

class CsvRow;
class Cursor;
class CsvReader;
class CsvLoader;
class CsvManager;
class CsvReaderFactory;
class CsvListenrInternalHandle;

/**
 * CSV文件改变事件回调函数.
 */
using CsvFileChangeListener =
    std::function<void(const std::string &, CsvManager *)>;

/**
 * CSV文件头描述
 */
using FieldDescriptor = std::map<std::string, std::size_t>;
const FieldDescriptor EmptyFieldDescriptor;

/**
 * 事件回调句柄
 */
class CsvListenrInternalHandle {
public:
  virtual ~CsvListenrInternalHandle() {}
};

/**
 * 事件回调句柄-注册者持有，任何需要监听文件变化者都需要持有这个句柄,
 * 事件监听器生命周期与句柄相同，当句柄释放则事件监听器也会失效
 */
using ListenerHandle = std::shared_ptr<CsvListenrInternalHandle>;

/**
 * CSV管理器.
 */
class CsvManager {
public:
  /**
   * 析构.
   *
   */
  virtual ~CsvManager() {}
  /**
   * 设置文件根目录, 目录内所有CSV文件都会被加载，但不包含子目录, 只支持一级目录内的文件，文件名必须以.csv作为扩展名
   *
   * \param root_dir 文件根目录
   * \return true或者false
   */
  virtual auto set_root_directory(const std::string &root_dir) -> bool = 0;
  /**
   * 启动.
   *
   * 独立的热更新检测线程也会同步启动
   * 
   * \param check_interval 热更新检查周期，秒
   * \return true或者false
   */
  virtual auto start(std::time_t check_interval = 60) -> bool = 0;
  /**
   * 关闭.
   *
   * \return true或者false
   */
  virtual auto stop() -> bool = 0;
  /**
   * 主循环.
   * 
   * 热更新事件回调将在这里被调用
   *
   * \return true或者false
   */
  virtual auto update() -> void = 0;
  /**
   * 添加文件变化事件监听器.
   *
   * \param file_name 文件名，不包含路径，譬如a.csv
   * \param listener 监听器回调
   * \return 监听器句柄
   */
  virtual auto add_listener(const std::string &file_name,
                            CsvFileChangeListener listener)
      -> ListenerHandle = 0;
  /**
   * 移除监听器.
   *
   * \param handle 监听器句柄
   * \return true或者false
   */
  virtual auto remove_listener(ListenerHandle handle) -> bool = 0;
  /**
   * 设置文件自动热更新.
   *
   * \param file_name 文件名，不包含路径，譬如a.csv
   * \param on_off true开启，false关闭
   * \return true或者false
   */
  virtual auto set_file_auto_reload(const std::string &file_name, bool on_off)
      -> bool = 0;
  /**
   * 设置读取器工厂.
   *
   * \param factory 工厂
   * \return 未设置前的工厂
   */
  virtual auto set_reader_factory(CsvReaderFactory *factory)
      -> CsvReaderFactory * = 0;
  /**
   * 建立并返回读取器.
   *
   * \param file_name 文件名，不包含路径，譬如a.csv
   * \param descriptor 列描述
   * \return 读取器
   */
  virtual auto new_reader(const std::string& file_name, const FieldDescriptor& descriptor = EmptyFieldDescriptor)
      -> std::unique_ptr<CsvReader> = 0;
  /**
   * 建立并返回读取器.
   *
   * \param file_name 文件名，不包含路径，譬如a.csv
   * \param use_first_row_as_descriptor 是否使用第一行作为列描述
   * \return 读取器
   */
  virtual auto new_reader(const std::string& file_name, bool use_first_row_as_descriptor)
      ->std::unique_ptr<CsvReader> = 0;
  /**
   * 忽略根目录内某个文件, 文件将不会被加载
   *
   * \param file_name 文件名
   * \return
   */
  virtual auto ignore(const std::string &file_name) -> void = 0;
};

/**
 * 读取器工厂.
 */
class CsvReaderFactory {
public:
  /**
   * 析构.
   *
   */
  virtual ~CsvReaderFactory() {}
  /**
   * 建立读取器.
   *
   * \param loader 加载器
   * \return 读取器
   */
  virtual auto create(CsvLoader *loader) -> CsvReader * = 0;
};

/**
 * 查询条件.
 */
struct CsvQuery {
  std::string index_name; ///< 索引名
  std::any key;           ///< 查询的值
};

/**
 * 游标.
 */
class Cursor {
public:
  /**
   * 析构.
   * 
   */
  virtual ~Cursor() {}
  /**
   * 获取结果集行数.
   * 
   * \return 结果集行数
   */
  virtual auto row_count() const noexcept -> std::size_t = 0;
  /**
   * 获取结果集列数.
   * 
   * \return 结果集列数
   */
  virtual auto column() const noexcept -> std::size_t = 0;
  /**
   * 结果集遍历器是否还有下一行可读.
   * 
   * \return true或者false
   */
  virtual auto has_next() const noexcept -> bool = 0;
  /**
   * 推进游标.
   * 
   * \return 
   */
  virtual auto next() const -> void = 0;
  /**
   * 检测游标是否有效.
   * 
   * \return 
   */
  virtual operator bool() const = 0; 
  /**
   * 获取字段数据.
   *
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(std::size_t col, std::string &value) const noexcept
      -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(std::size_t col,
                   std::vector<std::string> &value) const noexcept -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto
  get(std::size_t col,
      std::unordered_map<std::string, std::string> &value) const noexcept
      -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(std::size_t col,
                   std::unordered_set<std::string> &value) const noexcept
      -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(std::size_t col,
                   std::map<std::string, std::string> &value) const noexcept
      -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(std::size_t col, std::set<std::string> &value) const noexcept
      -> bool = 0;
  /**
   * 重置游标到结果集第一行.
   *
   * \return
   */
  virtual auto reset() const -> void = 0;
  /**
   * 获取字段数据.
   *
   * \param field_name 列名
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(const std::string& field_name, std::string& value) const noexcept
      -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param field_name 列名
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(const std::string& field_name,
      std::vector<std::string>& value) const noexcept -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param field_name 列名
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto
      get(const std::string& field_name,
          std::unordered_map<std::string, std::string>& value) const noexcept
      -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param field_name 列名
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(const std::string& field_name,
      std::unordered_set<std::string>& value) const noexcept
      -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param field_name 列名
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(const std::string& field_name,
      std::map<std::string, std::string>& value) const noexcept
      -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param field_name 列名
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(const std::string& field_name, std::set<std::string>& value) const noexcept
      -> bool = 0;
  /**
   * 按照数组下标获取列值, 支持基础类型
   */
  template <typename T> auto at(std::size_t col) const noexcept(false) -> T {
      T value;
      if (!try_get<T>(col, value)) {
          throw std::runtime_error("Field not found");
      }
      return value;
  }
  /**
   * 按照列名获取列值, 支持基础类型
   */
  template <typename T> auto at(const std::string& field_name) const noexcept(false) -> T {
      T value;
      if (!try_get<T>(field_name, value)) {
          throw std::runtime_error("Field not found");
      }
      return value;
  }
  /**
   * 获取列名为field_name的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T> auto try_get(const std::string& field_name, T& value) const noexcept -> bool {
      static thread_local std::string csv_value;
      csv_value.clear();
      if (!get(field_name, csv_value)) {
          return false;
      }
      try {
          std::stringstream ss;
          ss << csv_value;
          ss >> value;
      }
      catch (...) {
          return false;
      }
      return true;
  }
  /**
   * 获取列名为field_name的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T>
  auto try_get(const std::string& field_name, std::vector<T>& value) const noexcept -> bool {
      static thread_local std::vector<std::string> csv_value;
      csv_value.clear();
      value.clear();
      if (!get(field_name, csv_value)) {
          return false;
      }
      try {
          std::stringstream ss;
          for (auto& s : csv_value) {
              T v;
              ss.clear();
              ss << s;
              ss >> v;
              value.emplace_back(v);
          }
      }
      catch (...) {
          return false;
      }
      return true;
  }
  /**
   * 获取列名为field_name的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename K, typename V>
  auto try_get(const std::string& field_name, std::unordered_map<K, V>& value) const noexcept -> bool {
      static thread_local std::unordered_map<std::string, std::string> csv_value;
      csv_value.clear();
      value.clear();
      if (!get(field_name, csv_value)) {
          return false;
      }
      try {
          std::stringstream ss;
          for (auto& [k, v] : csv_value) {
              ss.clear();
              K map_key;
              V map_value;
              ss << k;
              ss >> map_key;
              ss.clear();
              ss << v;
              ss >> map_value;
              value.emplace(map_key, map_value);
          }
      }
      catch (...) {
          return false;
      }
      return true;
  }
  /**
   * 获取列名为field_name的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T>
  auto try_get(const std::string& field_name, std::unordered_set<T>& value) const noexcept -> bool {
      static thread_local std::unordered_set<std::string> csv_value;
      csv_value.clear();
      value.clear();
      if (!get(field_name, csv_value)) {
          return false;
      }
      try {
          std::stringstream ss;
          for (auto& s : csv_value) {
              T v;
              ss.clear();
              ss << s;
              ss >> v;
              value.emplace(v);
          }
      }
      catch (...) {
          return false;
      }
      return true;
  }
  /**
   * 获取列名为field_name的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename K, typename V>
  auto try_get(const std::string& field_name, std::map<K, V>& value) const noexcept -> bool {
      static thread_local std::map<std::string, std::string> csv_value;
      csv_value.clear();
      value.clear();
      if (!get(field_name, csv_value)) {
          return false;
      }
      try {
          std::stringstream ss;
          for (auto& [k, v] : csv_value) {
              ss.clear();
              K map_key;
              V map_value;
              ss << k;
              ss >> map_key;
              ss.clear();
              ss << v;
              ss >> map_value;
              value.emplace(map_key, map_value);
          }
      }
      catch (...) {
          return false;
      }
      return true;
  }
  /**
   * 获取列名为field_name的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T>
  auto try_get(const std::string& field_name, std::set<T>& value) const noexcept -> bool {
      static thread_local std::set<std::string> csv_value;
      csv_value.clear();
      value.clear();
      if (!get(field_name, csv_value)) {
          return false;
      }
      try {
          std::stringstream ss;
          for (auto& s : csv_value) {
              T v;
              ss.clear();
              ss << s;
              ss >> v;
              value.emplace(v);
          }
      }
      catch (...) {
          return false;
      }
      return true;
  }
  /**
   * 获取位于col列的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T> auto try_get(std::size_t col, T &value) const noexcept -> bool {
    static thread_local std::string csv_value;
    csv_value.clear();
    if (!get(col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      ss << csv_value;
      ss >> value;
    } catch (...) {
      return false;
    }
    return true;
  }
  /**
   * 获取位于col列的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T>
  auto try_get(std::size_t col, std::vector<T> &value) const noexcept -> bool {
    static thread_local std::vector<std::string> csv_value;
    csv_value.clear();
    value.clear();
    if (!get(col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      for (auto &s : csv_value) {
        T v;
        ss.clear();
        ss << s;
        ss >> v;
        value.emplace_back(v);
      }
    } catch (...) {
      return false;
    }
    return true;
  }
  /**
   * 获取位于col列的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename K, typename V>
  auto try_get(std::size_t col, std::unordered_map<K, V> &value) const noexcept -> bool {
    static thread_local std::unordered_map<std::string, std::string> csv_value;
    csv_value.clear();
    value.clear();
    if (!get(col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      for (auto &[k, v] : csv_value) {
        ss.clear();
        K map_key;
        V map_value;
        ss << k;
        ss >> map_key;
        ss.clear();
        ss << v;
        ss >> map_value;
        value.emplace(map_key, map_value);
      }
    } catch (...) {
      return false;
    }
    return true;
  }
  /**
   * 获取位于col列的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T>
  auto try_get(std::size_t col, std::unordered_set<T> &value) const noexcept -> bool {
    static thread_local std::unordered_set<std::string> csv_value;
    csv_value.clear();
    value.clear();
    if (!get(col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      for (auto &s : csv_value) {
        T v;
        ss.clear();
        ss << s;
        ss >> v;
        value.emplace(v);
      }
    } catch (...) {
      return false;
    }
    return true;
  }
  /**
   * 获取位于col列的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename K, typename V>
  auto try_get(std::size_t col, std::map<K, V> &value) const noexcept -> bool {
    static thread_local std::map<std::string, std::string> csv_value;
    csv_value.clear();
    value.clear();
    if (!get(col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      for (auto &[k, v] : csv_value) {
        ss.clear();
        K map_key;
        V map_value;
        ss << k;
        ss >> map_key;
        ss.clear();
        ss << v;
        ss >> map_value;
        value.emplace(map_key, map_value);
      }
    } catch (...) {
      return false;
    }
    return true;
  }
  /**
   * 获取位于col列的值
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T>
  auto try_get(std::size_t col, std::set<T> &value) const noexcept -> bool {
    static thread_local std::set<std::string> csv_value;
    csv_value.clear();
    value.clear();
    if (!get(col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      for (auto &s : csv_value) {
        T v;
        ss.clear();
        ss << s;
        ss >> v;
        value.emplace(v);
      }
    } catch (...) {
      return false;
    }
    return true;
  }
};

/**
 * 查询结果.
 */
class Result {
public:
    /**
   * 析构.
   *
   */
  virtual ~Result() {}
  /**
   * 获取游标，用于访问结果集.
   * 
   * \return 游标
   */
  virtual auto get_cursor() const noexcept -> const Cursor & = 0;
  /**
   * 检测结果是否有效  
   */
  virtual operator bool() const = 0;
};

/**
 * CSV读取器.
 * 
 * 可以通过CsvReaderFactory来建立自定义读取器
 * 
 */
class CsvReader {
public:
  /**
   * 析构.
   *
   */
  virtual ~CsvReader() {}

  /**
   * 获取行数.
   *
   * \return 行数
   */
  virtual auto get_row() const noexcept -> std::size_t = 0;

  /**
   * 获取列数.
   *
   * \return 列数
   */
  virtual auto get_column() const noexcept -> std::size_t = 0;

  /**
   * 使用某一列做为索引.
   *
   * \param col 列序号
   * \param index_name 索引名
   * \param type_info std::type_info
   * \return true或false
   */
  virtual auto create_index_by_type(std::size_t col,
                                    const std::string &index_name,
                                    const std::type_info *type_info)
      noexcept -> bool = 0;
  /**
   * 获取全文.
   * 
   * \return 结果集
   */
  virtual auto find_all() noexcept -> const Result& = 0;
  /**
   * 根据索引搜索.
   *
   * \param query 搜索条件
   * \return 结果集
   */
  virtual auto find(std::initializer_list<CsvQuery> query)
      noexcept -> const Result & = 0;

  /**
   * 根据索引搜索.
   *
   * \param query_key 键
   * \return 结果集
   */
  virtual auto find(std::initializer_list<std::any> query_key)
      noexcept -> const Result & = 0;
  /**
   * 获取某一行.
   * 
   * \param row 行序号
   * \return 结果集
   */
  virtual auto get(std::size_t row) noexcept -> const Result & = 0;
  /**
   * 获取字段数据.
   *
   * \param row 行
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(std::size_t row, std::size_t col, std::string &value)
      noexcept -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param row 行
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(std::size_t row, std::size_t col,
                   std::vector<std::string> &value) noexcept -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param row 行
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(std::size_t row, std::size_t col,
                   std::unordered_map<std::string, std::string> &value)
      noexcept -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param row 行
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(std::size_t row, std::size_t col,
                   std::unordered_set<std::string> &value) noexcept -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param row 行
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(std::size_t row, std::size_t col,
                   std::map<std::string, std::string> &value) noexcept -> bool = 0;
  /**
   * 获取字段数据.
   *
   * \param row 行
   * \param col 列
   * \param [OUT] value 字段数据
   * \return true或者false
   */
  virtual auto get(std::size_t row, std::size_t col,
                   std::set<std::string> &value) noexcept -> bool = 0;
  /**
   * 获取最新的错误.
   *
   * \return 最新的错误
   */
  virtual auto get_last_error() noexcept -> const std::string & = 0;

  /**
   * 重建索引.
   *
   * \return
   */
  virtual auto rebuild_index() noexcept -> bool = 0;

  /**
   * 设置列描述
   * \param descriptor 列描述
   */
  virtual auto set_descriptor(const FieldDescriptor& descriptor) -> void = 0;

  /**
   * 获取列描述
   * \return 列描述
   */
  virtual auto get_descriptor() const -> const FieldDescriptor & = 0;

  /**
   * 设置不读取的行数  
   */
  virtual auto set_skip_line(std::size_t skip_line) const -> void = 0;

  /**
   * 创建索引.
   * 
   * \param col 索引列
   * \param index_name 索引名
   * \return true或者false
   */
  template <typename T>
  auto create_index(std::size_t col, const std::string &index_name) -> bool {
    return create_index_by_type(col, index_name, &typeid(T));
  }
  /**
   * 获取位于row行col列的值
   * \param row 行序号
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T>
  auto try_get(std::size_t row, std::size_t col, T &value) -> bool {
    static thread_local std::string csv_value;
    csv_value.clear();
    if (!get(row, col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      ss << csv_value;
      ss >> value;
    } catch (...) {
      return false;
    }
    return true;
  }
  /**
   * 获取位于row行col列的值
   * \param row 行序号
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T>
  auto try_get(std::size_t row, std::size_t col, std::vector<T> &value)
      -> bool {
    static thread_local std::vector<std::string> csv_value;
    csv_value.clear();
    if (!get(row, col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      for (auto &s : csv_value) {
        T v;
        ss.clear();
        ss << s;
        ss >> v;
        value.emplace_back(v);
      }
    } catch (...) {
      return false;
    }
    return true;
  }
  /**
   * 获取位于row行col列的值
   * \param row 行序号
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename K, typename V>
  auto try_get(std::size_t row, std::size_t col,
               std::unordered_map<K, V> &value) -> bool {
    static thread_local std::unordered_map<std::string, std::string> csv_value;
    csv_value.clear();
    if (!get(row, col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      for (auto &[k, v] : csv_value) {
        ss.clear();
        K map_key;
        V map_value;
        ss << k;
        ss >> map_key;
        ss.clear();
        ss << v;
        ss >> map_value;
        value.emplace(map_key, map_value);
      }
    } catch (...) {
      return false;
    }
    return true;
  }
  /**
   * 获取位于row行col列的值
   * \param row 行序号
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T>
  auto try_get(std::size_t row, std::size_t col, std::unordered_set<T> &value)
      -> bool {
    static thread_local std::unordered_set<std::string> csv_value;
    csv_value.clear();
    if (!get(row, col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      for (auto &s : csv_value) {
        T v;
        ss.clear();
        ss << s;
        ss >> v;
        value.emplace(v);
      }
    } catch (...) {
      return false;
    }
    return true;
  }
  /**
   * 获取位于row行col列的值
   * \param row 行序号
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename K, typename V>
  auto try_get(std::size_t row, std::size_t col, std::map<K, V> &value)
      -> bool {
    static thread_local std::map<std::string, std::string> csv_value;
    csv_value.clear();
    if (!get(row, col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      for (auto &[k, v] : csv_value) {
        ss.clear();
        K map_key;
        V map_value;
        ss << k;
        ss >> map_key;
        ss.clear();
        ss << v;
        ss >> map_value;
        value.emplace(map_key, map_value);
      }
    } catch (...) {
      return false;
    }
    return true;
  }
  /**
   * 获取位于row行col列的值
   * \param row 行序号
   * \param col 列序号
   * \param [OUT] value 值
   * \return true或false
   */
  template <typename T>
  auto try_get(std::size_t row, std::size_t col, std::set<T> &value) -> bool {
    static thread_local std::set<std::string> csv_value;
    csv_value.clear();
    if (!get(row, col, csv_value)) {
      return false;
    }
    try {
      std::stringstream ss;
      for (auto &s : csv_value) {
        T v;
        ss.clear();
        ss << s;
        ss >> v;
        value.emplace(v);
      }
    } catch (...) {
      return false;
    }
    return true;
  }
};

/**
 * CSV一行数据.
 */
class CsvRow {
public:
  /**
   * 析构.
   *
   */
  virtual ~CsvRow() {}
  /**
   * 获取字段值.
   *
   * \param col 列
   * \param [OUT] value 字段值
   * \return true或者false
   */
  virtual auto get(std::size_t col, std::string &value) const noexcept
      -> bool = 0;
};

/**
 * CSV loader, following https://tools.ietf.org/html/rfc4180.
 */
class CsvLoader {
public:
  /**
   * 析构.
   *
   */
  virtual ~CsvLoader() {}
  /**
   * 加载一个CSV文件.
   *
   * \param file_path 文件路径
   * \param skip_line 忽略前面行数
   * \return true或者false
   */
  virtual auto load(const std::string &file_path, std::size_t skip_line)
      -> bool = 0;
  /**
   * 设置自动热加载.
   *
   * \param on_off true或者false
   * \return true或者false
   */
  virtual auto set_auto_reload(bool on_off) -> bool = 0;
  /**
   * 是否自动热加载.
   *
   * \return true或者false
   */
  virtual auto is_auto_reload() -> bool = 0;
  /**
   * 获取上次更新的时间戳.
   *
   * \return 上次更新的时间戳
   */
  virtual auto get_last_update_timestamp() -> std::time_t = 0;
  /**
   * 检测是否自某个时间戳（秒）被更新过.
   *
   * \param ts 时间戳（秒）
   * \return true或者false
   */
  virtual auto is_modified_since(std::time_t ts) -> bool = 0;
  /**
   * CSV文件内行数量.
   *
   * \return 文件内行数量
   */
  virtual auto row_count() -> std::size_t = 0;
  /**
   * 获取某一行.
   *
   * \param row 行序号
   * \return 某一行
   */
  virtual auto get_row(std::size_t row) -> const CsvRow * = 0;
  /**
   * 获取最新的错误.
   *
   * \return 最新的错误
   */
  virtual auto get_last_error() -> const std::string & = 0;
};

} // namespace util
} // namespace kratos
